package com.gl.battleship.services;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gl.battleship.domain.Constants;
import com.gl.battleship.domain.Game;
import com.gl.battleship.domain.Notification;
import com.gl.battleship.domain.Player;
import com.gl.battleship.domain.User;
import com.gl.battleship.domain.UserState;
import com.gl.battleship.domain.exceptions.MessagesExceptions;
import com.gl.battleship.domain.exceptions.PlayerException;
import com.gl.battleship.services.exceptions.GameException;
import com.gl.battleship.services.exceptions.NotificationException;
import com.gl.battleship.services.exceptions.UserException;
import com.gl.battleship.services.managers.IGameManager;
import com.gl.battleship.services.managers.IUserManager;
import com.gl.battleship.services.managers.NotificationManager;

@Service
public class BattleshipServices implements IBattleshipServices{

	@Autowired
	private IUserManager userManager;
	
	@Autowired
	private IGameManager gameManager;
	
		
	/**
	 * Login 
	 * 
	 * @param user is the user name who want to enter in the game 
	 * @param password is the password who want to enter in the game
	 * @return securityToken is an string that identified the user
	 */
	public String login(String user, String password) throws UserException {
		
		return userManager.logIn(user, password);
	}

	
	/**
	 * LogOut 
	 * 
	 * @param securityToken is the String that identified the user
	 * @return 'VALID' is an String that confirms the user unlogged
	 * @throws UserException 
	 * @throws GameException 
	 */
	public String logOut(String securityToken) throws UserException, GameException {
		
		User userLogOut = userManager.getUser(securityToken);

		  if (userLogOut.getStateUser().equals(UserState.NOT_AVAILABLE)){
			  String nick=userLogOut.getNick();
			  gameManager.retiredWar(nick);
		  }
		  
		  return userManager.logOut(securityToken);
	}
	

	/**
	 * List the users for states
	 * 
	 * @param securityToken is the security token of the user that requires the list
	 * @param userState is the state of the user list required: ALL,AVAILABLE,NOTAVAILABLE.
	 * @return List of users for the state required 
	 * 
	 */
	public List<String> getUsersByState(String securityToken,UserState userState) throws UserException{	
		List<User>users=userManager.listUsersByState(securityToken, userState);
		List <String> listUsers= new ArrayList<String>();
		for(User user:users){
			listUsers.add(user.getNick());
		}
	return listUsers;
	}
	
	
	/**
	 * String List of Active Users
	 * 
	 * @return List of active users 
	 */

	public List<String> getActiveUsers() throws UserException{	
		List<User>users=userManager.listActiveUsers();
		List <String> listUsers= new ArrayList<String>();
		for(User user:users){
			listUsers.add(user.getNick());
		}
	return listUsers;
	}
	
	
	/**
	 * User declares war on another user
	 * 
	 * @param securityToken SecurityToken of user who declared the war
	 * @param opponent is the nick of opponent user 
	 * @return warToken, is an String that identified the war declared, or 'INVALID PARTICIPANT' 
	 * @throws UserException
	 * @throws PlayerException 
	 * @throws GameException 
	 */
	public String declareWar(String securityToken, String opponent) throws UserException, PlayerException, GameException {

		User user = userManager.getUser(securityToken);
		String warTokenGame = new String();
		//a Null opponentUser is a user that doesn't exist. 
		User opponentUser = userManager.getUserByNick(opponent);
		if(opponentUser!=null){
			Game game= gameManager.declareWar(user, opponentUser);
			warTokenGame = game.getWarkToken();
		
		}
		
		return warTokenGame;
	}
	
	
	/**
	 * Accept the participant(opponent) to start the war
	 * 
	 * @param securityToken is a String that identified the participant who accepted the war
	 * @param warToken is a String that identified the war declared
	 * @throws UserException
	 * @throws GameException
	 * @throws PlayerException
	 * @return answerToWar is an String,'VALID', that confirms the war accepted 
	 * 
	 */
	public String acceptWar(String securityToken, String warToken) throws UserException,GameException, PlayerException {
		
		String answerToWar;
		User user = userManager.getUser(securityToken);
		answerToWar=gameManager.acceptWar(user, warToken);
	
		return answerToWar;
	}
	
	
	/**
	 * Refuse the war declared
	 * 
	 * @param securityToken is a String that identified the participant who canceled the war
	 * @param warToken is a String that identified the war declared
     * @throws UserException
	 * @throws GameException
	 * @throws PlayerException
	 * @return answerToWar is an String,'VALID', that confirms the war refused 
	 */
	
	public String refuseWar(String securityToken, String warToken) throws UserException,GameException, PlayerException {
		
		String answerToWar;
		User user = userManager.getUser(securityToken);
		answerToWar=gameManager.refuseWar(user, warToken);
	
		return answerToWar;
	}
	
	public String retiredWar(String nick) throws GameException{
		String answer;
		answer=gameManager.retiredWar(nick);
		return answer;
	}
	
	
	/**
	 * validate the Fleet created for the player 
	 * 
	 * @param securityToken received in login for validate session
	 * @param warToken contains the token with the war that want to validate the fleet
	 * @param fleet contains a string with the player's board and the fleet
	 * @return answerToWar is an String,'VALID', that confirms the fleet created
	 * 
	 */
	public String validateFleet(String securityToken, String warToken,
			String fleet) throws UserException,GameException, PlayerException {	
		
			//Throw UserException if user is null
			User user = userManager.getUser(securityToken);
			
			//Return valid if all is OK
			return gameManager.validateFleet(user, warToken, fleet);
	}
	
	
	/**
	 * shoot 
	 * 
	 * @param securityToken received in login for validate session
	 * @param warToken contains the token with the war that want to shoot
	 * @param x horizontal position for shoot
	 * @param y vertical position for shoot
	 * @return WATER, HIT, HIT/SUNK, HIT/SUNK/WIN according to shooting
	 * 
	 */
	public String shoot(String securityToken, String warToken, int x, String y) throws UserException, GameException, PlayerException {
		
		User user = userManager.getUser(securityToken);
		
		return gameManager.shoot(warToken, x, y, user);
	}
	
	
	/**
	 * Get Notifications of an user 
	 * 
	 * @param nick is the nick name of the user
	 * @return List <Notification> of the user called whit this nick
	 * @throws NotificationException 
	 */
	public List<Notification> getNotification(String nick) throws UserException, NotificationException{	
		return NotificationManager.listNotification(nick);		

	}
	
	
	public List<Notification> getNotificationState(String nick, String state) throws UserException{	
		return NotificationManager.listNotificationState(nick, state);		

	}

	
	
}
